/*function Promise(){
	this._thens = [];
}

Promise.prototype = {

	then : function (onResolve,onReject) {
		this._thens.push({resolve: onResolve, reject: onReject});
	},

	resolve : function(val){
		this._complete('resolve',val)
	},

	reject : function(reason){
		this._complete('reject',reason)
	},

	_complete : function(which,arg){
		this.then = which == 'resolve' ?
					function(resolve,reject){resolve && resolve(arg)} : 
					function(resolve,reject){reject && reject(arg)};

		this.resolve = this.reject = 
			function () { throw new Error('Promise already completed.'); };

		var aThen,i=0;
		while(aThen = this._thens[i++]){
			aThen[which] && aThen[which](arg);
		}

		delete this._thens;
	}
}

var p = new Promise();

p.then(function(val){
	console.log(val)
});

p.resolve(123);

p.then(function(val){
	console.log(val);
})*/



var PENDING = 0,
	FULFILLED = 1,
	REJECTED = 2;

function Promise(fn) {

	var state = PENDING;
	var value = null;
	var handlers = [];

	function fulfill(result) {
		state = FULFILLED;
		value = result;
		handlers.forEach(handle);
		handlers = null;
	}
	// 失败状态变化
	function reject(error) {
		state = REJECTED;
		value = error;
		handlers.forEach(handle);
		handlers = null;
	}


	function handle(handler) {
		if (state === PENDING) {
			handlers.push(handler);
		} else {
			if (state === FULFILLED &&
				typeof handler.onFulfilled === 'function') {
				handler.onFulfilled(value);
			}
			if (state === REJECTED &&
				typeof handler.onRejected === 'function') {
				handler.onRejected(value);
			}
		}
	}

	function resolve(result) {
		try {
			/*var then = getThen(result);
			if (then) {
				doResolve(then.bind(result), resolve, reject)
				return
			}*/
			fulfill(result);
		} catch (e) {
			reject(e);
		}
	}

	/*function getThen(value) {
		var t = typeof value;
		if (value && (t === 'object' || t === 'function')) {
			var then = value.then;
			if (typeof then === 'function') {
				return then;
			}
		}
		return null;
	}*/

	

	function doResolve(fn, onFulfilled, onRejected) {
		var done = false;

		try {
			fn(function(value) {
				if (done) return;
				done = true;
				onFulfilled(value);
			}, function(reason) {
				if (done) return;
				done = true;
				onRejected(reason);
			})
		} catch (ex) {
			if (done) return;
			done = true;
			onRejected(ex);
		}
	}

	this.done = function(onFulfilled, onRejected) {
		// 保证异步
		setTimeout(function() {
			handle({
				onFulfilled: onFulfilled,
				onRejected: onRejected
			});
		}, 0);
	}

	this.then = function(onFulfilled, onRejected) {

		return new Promise((resolve, reject) => {

			return this.done(function(result) {
				if (typeof onFulfilled === 'function') {
					try {
						// onFulfilled方法要有返回值！
						return resolve(onFulfilled(result));
					} catch (ex) {
						return reject(ex);
					}
				} else {
					return resolve(result);
				}
			}, function(error) {
				if (typeof onRejected === 'function') {
					try {
						return resolve(onRejected(error));
					} catch (ex) {
						return reject(ex);
					}
				} else {
					return reject(error);
				}
			});
		});
	}

	doResolve(fn, resolve, reject);



}



function MyPromise(fn){
	var state = PENDING;
	var value = null;
	var handlers = [];

	function fulfill(result){
		state = FULFILLED;
		value = result;
		handlers.forEach(handle)
		handlers = null;
	}

	function reject(reason){
		state = REJECTED;
		value = reason;
		handlers.forEach(handle);
		handlers = null;
	}

	function handle(handler){
		if(state == PENDING){
			handlers.push(handler)
		}
		else{
			if(state == FULFILLED && typeof handler.onFulfilled == 'function'){
				handler.onFulfilled(value);
			}
			if(state == REJECTED && typeof handler.onRejected == 'function'){
				handler.onRejected(value);
			}
		}
	}

	function resolve(result){
		try{
			fulfill(result);
		}
		catch(ex){
			reject(ex);
		}
	}

	function doResolve(fn,onFulfilled,onRejected){
		var done = false;
		try{
			fn(function(value){
				if(done)return;
				done = true;
				onFulfilled(value);
			},function(reason){
				if(done)return;
				done = true;
				onRejected(reason);
			})
		}
		catch(ex){
			if(done)return;
			done = true;
			onRejected(ex);
		}
	}


	this.done = function(onFulfilled,onRejected){
		setTimeout(()=>{
			handle({"onFulfilled":onFulfilled,"onRejected":onRejected});
		},0)
	}

	this.then = function(onFulfilled,onRejected){
		return new MyPromise((resolve,reject) => {
			return this.done(function(result){

				if(typeof onFulfilled == 'function'){
					try{
						return resolve(onFulfilled(result));
					}
					catch(ex){
						return reject(ex);
					}
				}
				else{
					return resolve(result);
				}

			},function(reason){

				if(typeof onRejected == 'function'){
					try{
						return resolve(onRejected(value));
					}
					catch(ex){
						return reject(ex);
					}
				}
				else{
					return reject(value)
				}

			});
		});
	}

	doResolve(fn,fulfill,reject);


}


var promiseCount = 0;

function testPromise() {
	var thisPromiseCount = ++promiseCount;
	var log = console.log;
	log('beforeend', thisPromiseCount + ') 开始(同步代码开始)');
	var p1 = new MyPromise(
		function(resolve, reject) {
			log('beforeend', thisPromiseCount + ') Promise开始(异步代码开始)');
			window.setTimeout(function() {
				resolve(thisPromiseCount);
			}, 2000);
		}
	);
	p1.then(
		function(val) {
			log('beforeend', val + ') Promise被满足了(异步代码结束)');
		}
	);
	log('beforeend', thisPromiseCount + ') 建立了Promise(同步代码结束)');
}

testPromise();

testPromise();




function binarySearch(array,val,left,right){
	if(left > right)return -1;

	var middle = Math.floor((left+right)/2);
	if(array[middle] == val)return middle;
	else if(array[middle]>val)return binarySearch(array,val,left,middle-1);
	else return binarySearch(array,middle,middle+1,right);
}



var PENDING = 0;
var FULFILLED = 1;
var REJECTED = 2;
function MyPromise(fn){


	var state = PENDING;
	var value = null;
	var handlers = [];

	function fulfill(result){
		state = FULFILLED;
		value = result;
		handlers.forEach(handle);
		handlers = []
	}

	function reject(reason){
		state = REJECTED;
		value = reason;
		handlers.forEach(handle);
		handlers = [];
	}

	function handle(handler){
		if(state == PENDING){
			handlers.push(handler);
		}
		else{
			if(state == FULFILLED && typeof handler.onFulfilled == 'function'){
				handler.onFulfilled(value);
			}
			if(state == REJECTED && typeof handler.onRejected == 'function'){
				handler.onRejected(value);
			}
		}
	}

	function resolve(result){
		try{
			fulfill(result);
		}
		catch(e){
			reject(e);
		}
	}

	function doResolve(fn,onFulfilled,onRejected){
		var done = false;

		try{
			fn(function(result){
				if(done)return;
				done = true;
				onFulfilled(result);
			},function(reason){
				if(done)return;
				done = true;
				onRejected(result);
			})
		}
		catch(e){
			if(done)return;
			done = true;
			onRejected(E);
		}
	}

	this.done = function(onFulfilled,onRejected){

		setTimeout(()=>{handle({"onFulfilled":onFulfilled,"onRejected":onRejected})},0);
	}

	this.then = function(onFulfilled,onRejected){
		return new Promise((resolve,reject)=>{
			this.done(function(result){
				if(typeof onFulfilled == 'function'){
					try{
						return resolve(onFulfilled(result));
						
					}
					catch(e){
						return reject(e)
					}
				}
				else{
					return resolve(result);
				}
			},function(reason){
				if(typeof onRejected == 'function'){
					try{
						return resolve(onRejected(result));
						
					}
					catch(e){
						return reject(e)
					}
				}
				else{
					return reject(result);
				}
			})
		})
	}


	doResolve(fn,fulfill,reject);

}


var promiseCount = 0;

function testPromise() {
	var thisPromiseCount = ++promiseCount;
	var log = console.log;
	log('beforeend', thisPromiseCount + ') 开始(同步代码开始)');
	var p1 = new MyPromise(
		function(resolve, reject) {
			log('beforeend', thisPromiseCount + ') Promise开始(异步代码开始)');
			window.setTimeout(function() {
				resolve(thisPromiseCount);
			}, 2000);
		}
	);
	p1.then(
		function(val) {
			log('beforeend', val + ') Promise被满足了(异步代码结束)');
		}
	);
	log('beforeend', thisPromiseCount + ') 建立了Promise(同步代码结束)');
}

testPromise();

testPromise();
